package com.wwfish.cmsui.modules.common.client.widget.xmlform;

import com.google.gwt.xml.client.*;
import com.nexustar.gwt.widgets.client.oper.SyncHttpRequestUtils;
import com.nexustar.gwt.widgets.client.ui.form.FormContainer;
import com.nexustar.gwt.widgets.client.ui.form.FormElement;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Tom
 * Date: 2010-8-4
 * Time: 15:05:42
 * To change this template use File | Settings | File Templates.
 */
public class XMLFormContainer extends FormContainer {
    private List<ElementMetaData> elements = new ArrayList();
    private IFormProvider provider;

    public XMLFormContainer(String path, int col) {
        this(path, col, null);
    }

    public XMLFormContainer(String path, int col, IFormProvider provider) {
        super(col);
        loadMappingXml(path);
        setProvider(provider);
        initElements();

    }

    public IFormProvider getProvider() {
        return provider;
    }

    public void setProvider(IFormProvider provider) {
        this.provider = provider;
    }

    private void initElements() {
        for (Iterator it = elements.iterator(); it.hasNext();) {
            ElementMetaData meta = (ElementMetaData) it.next();
            FormElement el = FormElementCreator.getFormElement(meta, provider);
            addElement(el);
        }
    }

    private void loadMappingXml(String path) {
        String xml = SyncHttpRequestUtils.syncGet(path);
        Document doc = XMLParser.parse(xml);
        NodeList treeList = doc.getElementsByTagName("elements");
        Element entry = (Element) treeList.item(0);
        NodeList nodes = entry.getChildNodes();

        for (int i = 0; i < nodes.getLength(); i++) {
            Node n = nodes.item(i);
            if (n.getNodeType() == Node.ELEMENT_NODE) {
//            if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeValue().replaceAll("[ \\n\\t\\r]", "").length() > 0) {
                if (n.getNodeName().equals("element")) {
                    parseElementNode((Element) n);
                }
            }
        }
    }

    private void parseElementNode(Element element) {
        ElementMetaData meta = new ElementMetaData();
        meta.setId(element.getAttribute("id"));
        NodeList attributes = element.getChildNodes();
        for (int i = 0; i < attributes.getLength(); i++) {
            Node tempNode = attributes.item(i);

            if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                if (tempNode.getNodeName().equals("labelType")) {
                    meta.setLabelType(tempNode.getFirstChild()==null?null:tempNode.getFirstChild().getNodeValue());
                } else if (tempNode.getNodeName().equals("labelText")) {
                    meta.setLabelText(tempNode.getFirstChild()==null?null:tempNode.getFirstChild().getNodeValue());
                } else if (tempNode.getNodeName().equals("property")) {
                    Element el = (Element) tempNode;
                    if (el.getAttribute("mapping") != null) {
                        meta.setMapping(el.getAttribute("mapping").equals("true"));
                    } else if (el.getAttribute("translator") != null) {
                        meta.setTranslator(el.getAttribute("translator"));
                    }
                    meta.setProperty(tempNode.getFirstChild()==null?null:tempNode.getFirstChild().getNodeValue());
                } else if (tempNode.getNodeName().equals("validator")) {
                    meta.setValidator(tempNode.getFirstChild()==null?null:tempNode.getFirstChild().getNodeValue());
                } else if (tempNode.getNodeName().equals("parameters")) {
                    parseParameters(meta, (Element) tempNode);
                }
            }
        }
        elements.add(meta);
    }

    private void parseParameters(ElementMetaData meta, Element parameters) {
        NodeList attributes = parameters.getChildNodes();
        List l = new ArrayList();
        for (int i = 0; i < attributes.getLength(); i++) {
            Node tempNode = attributes.item(i);
            if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                if (tempNode.getNodeName().equals("parameter")) {
                    l.add(tempNode.getFirstChild()==null?null:tempNode.getFirstChild().getNodeValue());
                }
            }
        }
        meta.setParameters(l);
    }

    class ElementMetaData {
        private String id;
        private String labelText;
        private String labelType;
        private String property;
        private boolean mapping = false;
        private String translator;
        private String validator;
        private List<String> parameters;

        public List<String> getParameters() {
            return parameters;
        }

        public void setParameters(List<String> parameters) {
            this.parameters = parameters;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getLabelText() {
            return labelText;
        }

        public void setLabelText(String labelText) {
            this.labelText = labelText;
        }

        public String getLabelType() {
            return labelType;
        }

        public void setLabelType(String labelType) {
            this.labelType = labelType;
        }

        public String getProperty() {
            return property;
        }

        public void setProperty(String property) {
            this.property = property;
        }

        public boolean isMapping() {
            return mapping;
        }

        public void setMapping(boolean mapping) {
            this.mapping = mapping;
        }

        public String getTranslator() {
            return translator;
        }

        public void setTranslator(String translator) {
            this.translator = translator;
        }

        public String getValidator() {
            return validator;
        }

        public void setValidator(String validator) {
            this.validator = validator;
        }
    }

}
